#pragma once

#include "ogl/gut/Texture2D.h"
#include "ogl/gut/TextureCube.h"

namespace Ogl
{
    namespace Pbrx
    {

        struct HdrTexture {


            std::shared_ptr<Ogl::Gut::TextureCube> irradianceMap;
            std::shared_ptr<Ogl::Gut::TextureCube> prefilterMap;
            std::shared_ptr<Ogl::Gut::TextureCube> envCubeMap;
            std::shared_ptr<Ogl::Gut::Texture2D> brdfLUTtexture;

            HdrTexture()
            {
                irradianceMap = std::make_shared<Ogl::Gut::TextureCube>();

                for (unsigned int i = 0; i < 6; ++i)
                {
                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 32, 32, 0, GL_RGB, GL_FLOAT, nullptr);
                }
                {
                    Ogl::Gut::SamplerDesc& sampDesc = irradianceMap->m_SampDesc;
                    sampDesc.wrapR = GL_CLAMP_TO_EDGE;
                    sampDesc.wrapS = GL_CLAMP_TO_EDGE;
                    sampDesc.wrapT = GL_CLAMP_TO_EDGE;
                    sampDesc.minFilter = GL_LINEAR;
                    sampDesc.magFilter = GL_LINEAR;
                    irradianceMap->SetSampler();
                }

                prefilterMap = std::make_shared<Ogl::Gut::TextureCube>();

                for (unsigned int i = 0; i < 6; ++i)
                {
                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 128, 128, 0, GL_RGB, GL_FLOAT, nullptr);
                }
                {
                    Ogl::Gut::SamplerDesc& sampDesc = prefilterMap->m_SampDesc;
                    sampDesc.wrapR = GL_CLAMP_TO_EDGE;
                    sampDesc.wrapS = GL_CLAMP_TO_EDGE;
                    sampDesc.wrapT = GL_CLAMP_TO_EDGE;
                    sampDesc.minFilter = GL_LINEAR_MIPMAP_LINEAR;
                    sampDesc.magFilter = GL_LINEAR;
                    prefilterMap->SetSampler();
                    prefilterMap->Mipmap();
                }

                // EnvCubemap Create
                envCubeMap = std::make_shared<Ogl::Gut::TextureCube>();

                for (unsigned int i = 0; i < 6; ++i)
                {
                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, nullptr);
                }
                {
                    Ogl::Gut::SamplerDesc& sampDesc = envCubeMap->m_SampDesc;
                    sampDesc.wrapR = GL_CLAMP_TO_EDGE;
                    sampDesc.wrapS = GL_CLAMP_TO_EDGE;
                    sampDesc.wrapT = GL_CLAMP_TO_EDGE;
                    sampDesc.minFilter = GL_LINEAR_MIPMAP_LINEAR;
                    sampDesc.magFilter = GL_LINEAR;
                    envCubeMap->SetSampler();
                }


                brdfLUTtexture = std::make_shared<Ogl::Gut::Texture2D>();
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, 512, 512, 0, GL_RG, GL_FLOAT, 0);
                Ogl::Gut::SamplerDesc& sampDesc = brdfLUTtexture->m_SampDesc;
                sampDesc.wrapR = GL_CLAMP_TO_EDGE;
                sampDesc.wrapT = GL_CLAMP_TO_EDGE;
                sampDesc.minFilter = GL_LINEAR;
                sampDesc.magFilter = GL_LINEAR;
                brdfLUTtexture->SetSampler();


            }
            void Active() const
            {

                irradianceMap->Active(0);
                prefilterMap->Active(1);
                brdfLUTtexture->Active(2);


            }
        };
    }
}